/*
 * @description:
 * @Author: jhw
 * @Date: 2025-06-30 11:12:21
 * @LastEditors: jhw
 * @LastEditTime: 2025-06-30 18:35:13
 */
import trigger from "../../effect/trigger.js";
import { TriggerOpTypes, hasChanged } from "../../utils.js";

export default function (target, key, value) {
  // 关于具体的操作类型需要进一步判断
  // 有可能是设置，有可能是新增
  const type = target.hasOwnProperty(key)
    ? TriggerOpTypes.SET
    : TriggerOpTypes.ADD;

  // 在设置之前需要缓存一下旧值
  const oldValue = target[key];
  // 先缓存旧的数组长度
  const oldLength = Array.isArray(target) ? target.length : undefined;

  // 先进行设置操作
  const result = Reflect.set(target, key, value);

  // 要不要派发更新需要一些判断
  if (hasChanged(oldValue, value)) {
    // 派发更新
    trigger(target, type, key);
    // 如果是数组的新增元素，还需要派发数组长度变化
    if (Array.isArray(target) && hasChanged(oldLength, target.length)) {
      if (key !== "length") {
        // 派发数组长度变化
        trigger(target, TriggerOpTypes.SET, "length");
      } else {
        // 如果是设置 length 属性，说明数组长度发生了变化
        // 这里不需要再派发一次，因为已经在上面派发过了
        // 如果数组长度小于 旧长度，说明有元素被删除
        if (target.length < oldLength) {
          for (let i = target.length; i < oldLength; i++) {
            // 这里需要派发删除操作
            trigger(target, TriggerOpTypes.DELETE, i);
          }
        }
      }
    }
  }

  return result;
}
